package org.lex.net.event;

import java.util.EventObject;

/**
 * There exists a large class of IETF protocols that work by sending an ASCII
 * text command and arguments to a server, and then receiving an ASCII text
 * reply. For debugging and other purposes, it is extremely useful to log or
 * keep track of the contents of the protocol messages.
 */
public class ProtocolEvent extends EventObject {
	private static final long serialVersionUID = -7199185851601495863L;
	private int replyCode = 0;
	private boolean isCommand = false;
	private String message = null;
	private String command = null;

	/***************************************************************************
	 * Creates a CommandEvent signalling a command was sent to the server.
	 * CommandEvent created with this constructor should only be sent after a
	 * command has been sent, but before the reply has been received.
	 * <p>
	 * 
	 * @param source
	 *            The source of the event.
	 * @param command
	 *            The string representation of the command type sent, not
	 *            including the arguments (e.g., "STAT" or "GET").
	 * @param message
	 *            The entire command string verbatim as sent to the server,
	 *            including all arguments.
	 **************************************************************************/
	public ProtocolEvent(Object source, String command, String message) {
		super(source);
		this.replyCode = 0;
		this.message = message;
		this.isCommand = true;
		this.command = command;
	}

	/***************************************************************************
	 * Creates a CommandEvent signalling a reply to a command was received.
	 * CommandEvent created with this constructor should only be sent after a
	 * complete command reply has been received fromt a server.
	 * <p>
	 * 
	 * @param source
	 *            The source of the event.
	 * @param replyCode
	 *            The integer code indicating the natureof the reply. This will
	 *            be the protocol integer value for protocols that use integer
	 *            reply codes, or the reply class constant corresponding to the
	 *            reply for protocols like POP3 that use strings like OK rather
	 *            than integer codes (i.e., POP3Repy.OK).
	 * @param message
	 *            The entire reply as received from the server.
	 **************************************************************************/
	public ProtocolEvent(Object source, int replyCode, String message) {
		super(source);
		this.replyCode = replyCode;
		this.message = message;
		this.isCommand = false;
		this.command = "";
	}

	/***************************************************************************
	 * Returns the string representation of the command type sent (e.g., "STAT"
	 * or "GET"). If the ProtocolCommandEvent is a reply event, then null is
	 * returned.
	 * <p>
	 * 
	 * @return The string representation of the command type sent, or null if
	 *         this is a reply event.
	 **************************************************************************/
	public String getCommand() {
		return command;
	}

	/***************************************************************************
	 * Returns the reply code of the received server reply. Undefined if this is
	 * not a reply event.
	 * <p>
	 * 
	 * @return The reply code of the received server reply. Undefined if not a
	 *         reply event.
	 **************************************************************************/
	public int getReplyCode() {
		return replyCode;
	}

	/***************************************************************************
	 * Returns true if the CommandEvent was generated as a result of sending a
	 * command.
	 * <p>
	 * 
	 * @return true If the CommandEvent was generated as a result of sending a
	 *         command. False otherwise.
	 **************************************************************************/
	public boolean isCommand() {
		return isCommand;
	}

	/***************************************************************************
	 * Returns true if the CommandEvent was generated as a result of receiving a
	 * reply.
	 * <p>
	 * 
	 * @return true If the CommandEvent was generated as a result of receiving a
	 *         reply. False otherwise.
	 **************************************************************************/
	public boolean isReply() {
		return !isCommand();
	}

	/***************************************************************************
	 * Returns the entire message sent to or received from the server.
	 * <p>
	 * 
	 * @return The entire message sent to or received from the server.
	 **************************************************************************/
	public String getMessage() {
		return message;
	}

	public String toString() {
		if (this.isCommand) {
			if (null == command || 0 == command.length())
				return this.message;
			else
				return this.command + " " + this.message;
		} else
			return this.message;
	}
}
